Crate attribute_derive

source ·
Expand description

Basicly clap for attribute macros:

#[derive(Attribute)]
#[attribute(ident = collection)]
#[attribute(error(missing_field = "`{field}` was not specified"))]
struct CollectionAttribute {
    // Options are optional by default (will be set to None if not specified)
    authority: Option<String>,
    name: String,
    // Any type implementing default can be flagged as default
    // This will be set to Vec::default() when not specified
    #[attribute(optional)]
    views: Vec<Type>,
    // Booleans can be used without assiging a value. as a flag.
    // If omitted they are set to false
    some_flag: bool,
}

Will be able to parse an attribute like this:

#[collection(authority="Some String", name = r#"Another string"#, views = [Option, ()])]

Any type that ConvertParsed is implemented for is supported. These should be the general types that syn supports like LitStr or Type or that have a direct equivalent in those like String, char or f32. A special treatment have Vecs which are parsed using Array with the syntax [a, b, c] and Options that will be None if not specified and Some when the value is specified via the attribute. It is not specified via Some(value) but as just value.

Attributes

The parsing of attributes can be modified with the following parameters via the #[attribute(<params>)] attribute. All of them are optional. Error messages are formatted using interpolator, and only support display and on lists i formatting. See interpolator docs for details.

Struct

  • ident = <ident> The attribute ident. Improves error messages and enables the from_attributes and remove_attributes functions.

  • aliases = [<alias>, ...] Aliases for the attribute ident.

  • error = "<error message>" Overrides default error message.

  • error(

    • unknown_field = "supported fields are {expected_fields:i..-1(`{}`)(, )} and `{expected_fields:i-1}`", Custom error message printed if an unknown property is specified and attribute has more than one field. Supports {found_field} and {expected_fields:i} placeholders.
    • unknown_field_single = "expected supported field `{expected_field}`", Custom error message printed if an unknown property is specified, and attribute only has a single field. Supports {found_field} and {expected_field} placeholders.
    • unknown_field_empty = "expected empty attribute", Custom error message printed if a property is specified, and attribute has no fields. Supports {found_field} placeholder.
    • duplicate_field = "`{field}` is specified multiple times", Custom error message printed if a property is specified multiple times. Supports {field} placeholder.
    • missing_field = "required `{field}` is not specified", Custom error message printed if a required property is not specified. Supports {field} placeholder.
    • field_help = "try `#[{attribute}({field}={example})]`", Additional help message printed if a required property is not specified or has an error. Supports {attribute}, {field} and {example} placeholder.
    • missing_flag = "required `{flag}` is not specified", Custom error message printed if a required flag is not specified. Supports {flag} placeholder.
    • flag_help = "try `#[{attribute}({flag})]`", Additional help message printed if a required flag is not specified. Supports {attribute} and {flag} placeholder.
    • conflict = "`{first}` conflicts with mutually exclusive `{second}`" Custom error message printed if conflicting properties are specified. Supports {first} and {second} placeholder.

    )

Fields

  • optional / optional = true If field is not specified, the default value is used instead.
  • optional = false Disables implicit optionality of Option, Vec and bool. Note that this makes Option<T> behave the same as T and makes a bool a mandatory flag.
  • default = <default expr> provides a default to be used instead of Default. Enables optional.
  • conflicts = [<field>, ...] Conflicting fields
  • example = "<example>"

Limitations

There are some limitations in syntax parsing that will be lifted in future releases.

  • literals in top level (meaning something like #[attr(42, 3.14, "hi")]
  • function like arguments (something like #[attr(view(a = "test"))]
  • other syntaxes, maybe something like key: value

Parse methods

There are multiple ways of parsing a struct deriving Attribute.

For helper attributes there is:

For parsing a single TokenStream e.g. for parsing the proc macro input there a two ways:

Structs

  • Helper struct to parse array literals: [a, b, c]
  • Helper struct to hold a value and the ident of its property

Traits